package proiect.fis.UI.tree;

import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.tree.*;

/**
 *
 * @author Boogie
 */
public class Tree<T> extends JTree {

    public static class TreeNode<T> extends DefaultMutableTreeNode {

        private String name;
        private T value;
        private Icon icon = null;

        public TreeNode() {
        }

        public TreeNode(String name, T value) {
            this.name = name;
            this.value = value;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public T getValue() {
            return value;
        }

        public void setValue(T value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return name;
        }

        public Icon getIcon() {
            return icon;
        }

        public void setIcon(Icon icon) {
            this.icon = icon;
        }
    }
    
    
    private List<TreeNodeClickedListener> listeners;
    private DefaultTreeCellRenderer renderer;
    private TreeNode<T> currentSelection = null;

    public Tree() {
        this.setModel(null);
        listeners = new LinkedList<>();
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent me) {
                for (TreeNodeClickedListener onTreeNodeClickedListener : listeners) {
                    TreePath tp = getPathForLocation(me.getX(), me.getY());

                    if (tp != null) {
                        TreeNode<T> tv = (TreeNode) tp.getLastPathComponent();
                        if (!tv.isRoot()) {
                            currentSelection = tv;
                            onTreeNodeClickedListener.onTreeNodeClicked(me, tv);
                            
                        }else{
                            currentSelection = null;
                        }

                    }else{
                        currentSelection = null;
                    }
                }
            }
        });
        renderer = new DefaultTreeCellRenderer() {

            @Override
            public Component getTreeCellRendererComponent(JTree jtree, Object o, boolean bln, boolean bln1, boolean leaf, int i, boolean bln3) {
                super.getTreeCellRendererComponent(jtree, o, bln, bln1, leaf, i, bln3);
                if (((TreeNode) o).getIcon() != null) {
                    this.setIcon(((TreeNode) o).getIcon());
                }
                return this;
            }
        };
        this.setCellRenderer(renderer);
    }

    @Override
    public void repaint() {
        super.repaint();
        for(int i =0; i < this.getRowCount();i++){
            this.expandRow(i);
            
        }
    }


    
    public void setOpenIcon(Icon icon) {
        renderer.setOpenIcon(icon);
    }

    public void setLeafIcon(Icon icon) {
        renderer.setLeafIcon(icon);
    }

    public void setClosedIcon(Icon icon) {
        renderer.setClosedIcon(icon);
    }
    
    public TreeNode<T> getSelectedNode(){
        return this.currentSelection;
    }
    public TreeNode findTreeNode(T value) {
        TreeModel m = this.getModel();
        TreeNode root = (TreeNode) m.getRoot();
        for(int i =0;i<m.getChildCount(root);i++){
            TreeNode current = ((TreeNode)m.getChild(root, i));
            if(current.getValue().equals(value)){
                return current;
            }
        }
        
        return null;
    }
    
    public T getSelectedValue(){
        return this.getSelectedNode().getValue();
    }
    
    public void addOnTreeNodeClickedListener(TreeNodeClickedListener listner) {
        listeners.add(listner);
    }

    public void removeOnTreeNodeClickedListener(TreeNodeClickedListener listener) {
        listeners.remove(listener);
    }
}
